package cn.sfrog.web.ueditor;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.baidu.ueditor.define.ActionMap;
import com.baidu.ueditor.define.AppInfo;
import com.baidu.ueditor.define.BaseState;
import com.baidu.ueditor.define.State;
import com.jfinal.core.NotAction;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.stereotype.Controller;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Controller
@CrossOrigin(origins = {"*", "null"})
@RequestMapping("/")
public class UeditorController {
    private JSONObject jsonConfig = null;

    private JSONObject getJsonConfig() {
        if (jsonConfig == null) {
            InputStream in = null;
            try {
                in = UeditorController.class.getResourceAsStream("/ueditor.json");
                jsonConfig = JSONObject.parseObject(IOUtils.toString(in, "utf-8"));
                System.out.println("jsonConfig == "+ jsonConfig);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                IOUtils.closeQuietly(in);
            }
        }
        return jsonConfig;
    }

    @CrossOrigin(origins = {"*", "null"})
    @RequestMapping(value = "/3rd/plugins/ueditor/jsp/action")
    @ResponseBody
    public String action(HttpServletRequest request,HttpServletResponse httpResponse) throws UnsupportedEncodingException {

        httpResponse.setHeader("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept");
        httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
        httpResponse.addHeader("Access-Control-Allow-Origin", "*");
        httpResponse.addHeader("Content-Type", "text/html;charset=UTF-8");

        String action = request.getParameter("action");
        System.out.println("action == "+ action);
        int actionCode = ActionMap.getType(action);
        switch (actionCode) {
            case ActionMap.UPLOAD_IMAGE:
            case ActionMap.UPLOAD_SCRAWL:
            case ActionMap.UPLOAD_VIDEO:
            case ActionMap.UPLOAD_FILE:
                ConfigManager configManager = new ConfigManager(getJsonConfig());
                Map<String, Object> conf = configManager.getConfig(actionCode);
                State state = doUpload(request, conf);
                return state.toJSONString();
            default:
                String resp = new ActionEnter(request, getJsonConfig()).exec();
                return resp;
        }
    }

    @NotAction
    private State doUpload(HttpServletRequest request, Map<String, Object> conf) {
        boolean isAjaxUpload = request.getHeader("X_Requested_With") != null;

        if (!ServletFileUpload.isMultipartContent(request)) {
            return new BaseState(false, AppInfo.NOT_MULTIPART_CONTENT);
        }

        try {
            MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) request;
            MultiValueMap<String, MultipartFile> fileMap = mRequest.getMultiFileMap();
            MultipartFile uploadFile = null;
            for (Map.Entry<String, List<MultipartFile>> entry : fileMap.entrySet()) {
                if (entry.getValue() == null) {
                    continue;
                }
                for (MultipartFile file : entry.getValue()) {
                    if (file == null || file.isEmpty()) {
                        continue;
                    }
                    uploadFile = file;
                    break;
                }
            }
            if (uploadFile == null) {
                return new BaseState(false, AppInfo.NOTFOUND_UPLOAD_DATA);
            }

            String type = "default";
            String saveDir = "admin/" + type + "/" + DateFormatUtils.format(new Date(), "yyyyMMdd");
            String originFileName = uploadFile.getOriginalFilename();
            String suffix = "." + FilenameUtils.getExtension(originFileName);

            originFileName = originFileName.substring(0, originFileName.length() - suffix.length());
            String saveName = IdUtil.fastSimpleUUID() + suffix;

            long maxSize = ((Long) conf.get("maxSize")).longValue();

            if (!ArrayUtils.contains((String[]) conf.get("allowFiles"), suffix)) {
                return new BaseState(false, AppInfo.NOT_ALLOW_FILE_TYPE);
            }

            InputStream is = uploadFile.getInputStream();
            State storageState = StorageManager.saveFileByInputStream(is, saveDir, saveName, maxSize);
            is.close();

            if (storageState.isSuccess()) {
                storageState.putInfo("type", suffix);
                storageState.putInfo("original", originFileName + suffix);
            }

            return storageState;
        } catch (Exception e) {
            return new BaseState(false, AppInfo.IO_ERROR);
        }
    }
}
